﻿using System;
using System.Diagnostics;
using System.Threading;
using Mono.Collections.Generic;

namespace Mono.Cecil
{
	// Token: 0x0200005E RID: 94
	[DebuggerDisplay("{AttributeType}")]
	public sealed class CustomAttribute : ICustomAttribute
	{
		// Token: 0x17000059 RID: 89
		// (get) Token: 0x06000388 RID: 904 RVA: 0x0001AA8C File Offset: 0x00018C8C
		// (set) Token: 0x06000389 RID: 905 RVA: 0x0000343B File Offset: 0x0000163B
		public MethodReference Constructor
		{
			get
			{
				return this.constructor;
			}
			set
			{
				this.constructor = value;
			}
		}

		// Token: 0x1700005A RID: 90
		// (get) Token: 0x0600038A RID: 906 RVA: 0x0001AAA4 File Offset: 0x00018CA4
		public TypeReference AttributeType
		{
			get
			{
				return this.constructor.DeclaringType;
			}
		}

		// Token: 0x1700005B RID: 91
		// (get) Token: 0x0600038B RID: 907 RVA: 0x0001AAC4 File Offset: 0x00018CC4
		public bool IsResolved
		{
			get
			{
				return this.resolved;
			}
		}

		// Token: 0x1700005C RID: 92
		// (get) Token: 0x0600038C RID: 908 RVA: 0x0001AADC File Offset: 0x00018CDC
		public bool HasConstructorArguments
		{
			get
			{
				this.Resolve();
				return !this.arguments.IsNullOrEmpty<CustomAttributeArgument>();
			}
		}

		// Token: 0x1700005D RID: 93
		// (get) Token: 0x0600038D RID: 909 RVA: 0x0001AB04 File Offset: 0x00018D04
		public Collection<CustomAttributeArgument> ConstructorArguments
		{
			get
			{
				this.Resolve();
				bool flag = this.arguments == null;
				if (flag)
				{
					Interlocked.CompareExchange<Collection<CustomAttributeArgument>>(ref this.arguments, new Collection<CustomAttributeArgument>(), null);
				}
				return this.arguments;
			}
		}

		// Token: 0x1700005E RID: 94
		// (get) Token: 0x0600038E RID: 910 RVA: 0x0001AB44 File Offset: 0x00018D44
		public bool HasFields
		{
			get
			{
				this.Resolve();
				return !this.fields.IsNullOrEmpty<CustomAttributeNamedArgument>();
			}
		}

		// Token: 0x1700005F RID: 95
		// (get) Token: 0x0600038F RID: 911 RVA: 0x0001AB6C File Offset: 0x00018D6C
		public Collection<CustomAttributeNamedArgument> Fields
		{
			get
			{
				this.Resolve();
				bool flag = this.fields == null;
				if (flag)
				{
					Interlocked.CompareExchange<Collection<CustomAttributeNamedArgument>>(ref this.fields, new Collection<CustomAttributeNamedArgument>(), null);
				}
				return this.fields;
			}
		}

		// Token: 0x17000060 RID: 96
		// (get) Token: 0x06000390 RID: 912 RVA: 0x0001ABAC File Offset: 0x00018DAC
		public bool HasProperties
		{
			get
			{
				this.Resolve();
				return !this.properties.IsNullOrEmpty<CustomAttributeNamedArgument>();
			}
		}

		// Token: 0x17000061 RID: 97
		// (get) Token: 0x06000391 RID: 913 RVA: 0x0001ABD4 File Offset: 0x00018DD4
		public Collection<CustomAttributeNamedArgument> Properties
		{
			get
			{
				this.Resolve();
				bool flag = this.properties == null;
				if (flag)
				{
					Interlocked.CompareExchange<Collection<CustomAttributeNamedArgument>>(ref this.properties, new Collection<CustomAttributeNamedArgument>(), null);
				}
				return this.properties;
			}
		}

		// Token: 0x17000062 RID: 98
		// (get) Token: 0x06000392 RID: 914 RVA: 0x0001AC14 File Offset: 0x00018E14
		internal bool HasImage
		{
			get
			{
				return this.constructor != null && this.constructor.HasImage;
			}
		}

		// Token: 0x17000063 RID: 99
		// (get) Token: 0x06000393 RID: 915 RVA: 0x0001AC3C File Offset: 0x00018E3C
		internal ModuleDefinition Module
		{
			get
			{
				return this.constructor.Module;
			}
		}

		// Token: 0x06000394 RID: 916 RVA: 0x00003445 File Offset: 0x00001645
		internal CustomAttribute(uint signature, MethodReference constructor)
		{
			this.signature = signature;
			this.constructor = constructor;
			this.resolved = false;
		}

		// Token: 0x06000395 RID: 917 RVA: 0x00003464 File Offset: 0x00001664
		public CustomAttribute(MethodReference constructor)
		{
			this.constructor = constructor;
			this.resolved = true;
		}

		// Token: 0x06000396 RID: 918 RVA: 0x0000347C File Offset: 0x0000167C
		public CustomAttribute(MethodReference constructor, byte[] blob)
		{
			this.constructor = constructor;
			this.resolved = false;
			this.blob = blob;
		}

		// Token: 0x06000397 RID: 919 RVA: 0x0001AC5C File Offset: 0x00018E5C
		public byte[] GetBlob()
		{
			bool flag = this.blob != null;
			byte[] result;
			if (flag)
			{
				result = this.blob;
			}
			else
			{
				bool flag2 = !this.HasImage;
				if (flag2)
				{
					throw new NotSupportedException();
				}
				result = this.Module.Read<CustomAttribute, byte[]>(ref this.blob, this, (CustomAttribute attribute, MetadataReader reader) => reader.ReadCustomAttributeBlob(attribute.signature));
			}
			return result;
		}

		// Token: 0x06000398 RID: 920 RVA: 0x0001ACC8 File Offset: 0x00018EC8
		private void Resolve()
		{
			bool flag = this.resolved || !this.HasImage;
			if (!flag)
			{
				object syncRoot = this.Module.SyncRoot;
				lock (syncRoot)
				{
					bool flag3 = this.resolved;
					if (!flag3)
					{
						this.Module.Read<CustomAttribute>(this, delegate(CustomAttribute attribute, MetadataReader reader)
						{
							try
							{
								reader.ReadCustomAttributeSignature(attribute);
								this.resolved = true;
							}
							catch (ResolutionException)
							{
								bool flag4 = this.arguments != null;
								if (flag4)
								{
									this.arguments.Clear();
								}
								bool flag5 = this.fields != null;
								if (flag5)
								{
									this.fields.Clear();
								}
								bool flag6 = this.properties != null;
								if (flag6)
								{
									this.properties.Clear();
								}
								this.resolved = false;
							}
						});
					}
				}
			}
		}

		// Token: 0x040000DB RID: 219
		internal CustomAttributeValueProjection projection;

		// Token: 0x040000DC RID: 220
		internal readonly uint signature;

		// Token: 0x040000DD RID: 221
		internal bool resolved;

		// Token: 0x040000DE RID: 222
		private MethodReference constructor;

		// Token: 0x040000DF RID: 223
		private byte[] blob;

		// Token: 0x040000E0 RID: 224
		internal Collection<CustomAttributeArgument> arguments;

		// Token: 0x040000E1 RID: 225
		internal Collection<CustomAttributeNamedArgument> fields;

		// Token: 0x040000E2 RID: 226
		internal Collection<CustomAttributeNamedArgument> properties;
	}
}
